package com.ucar.common.interceptor;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.ucar.common.annotation.LogExecuteMethodOfControllerAnnotation;

/**
 * 自定义拦截器
 * HandlerInterceptoer拦截的是请求地址，功能能跟Filter类似，但是提供更精细的的控制能力：
 * 在request被响应之前、request被响应之后、视图渲染之前以及request全部结束之后。
 * 所以针对请求地址做一些验证、预处理等操作比较合适。也可以用作计算一个请求的相应时间等。【必须过DispatcherServlet的请求才会被拦截】
 * 
 * @author dinghao
 *
 */
public class LogExecuteMethodOfControllerInterceptor extends HandlerInterceptorAdapter {
	private Logger logger = LoggerFactory.getLogger(getClass());

	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSXXX");

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		Method method = handlerMethod.getMethod();
		String className = method.getDeclaringClass().getName();
		// 获取当前方法上的指定注解
		LogExecuteMethodOfControllerAnnotation loggerAnnotation = method
				.getAnnotation(LogExecuteMethodOfControllerAnnotation.class);
		// 判断当前注解是否存在
		if (loggerAnnotation != null) {
			long startTime = System.currentTimeMillis();
			request.setAttribute("startTime", startTime);
			String startTimeFormat = sdf.format(new Date(startTime));
			logger.info("进入{}类的{}方法的时间是:{}", className, method, startTimeFormat);
		}
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		Method method = handlerMethod.getMethod();
		// 获取当前方法上的指定注解
		LogExecuteMethodOfControllerAnnotation loggerAnnotation = method
				.getAnnotation(LogExecuteMethodOfControllerAnnotation.class);
		// 判断当前注解是否存在
		if (loggerAnnotation != null) {
			long endTime = System.currentTimeMillis();
			long startTime = (Long) request.getAttribute("startTime");
			long periodTime = endTime - startTime;
			String startTimeFormat = sdf.format(new Date(endTime));
			logger.info("离开{}类{}方法的时间是:{}", method.getDeclaringClass().getName(), method.getName(), startTimeFormat);
			logger.info("执行{}类{}方法的时长是:{}ms", method.getDeclaringClass().getName(), method.getName(), periodTime);
		}
	}

}
